﻿using System;
using System.Reactive.Subjects;
using Sbcx;
using Sbcx.ComponentModel;

namespace StreamBase.SB.Client {

    public static class ToObservableExtensions {

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, StreamProperties props) {
            return Create (streamBaseClient, client => client.Subscribe (props));
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, StreamProperties props, ObservableOptions options) {
            return Create (streamBaseClient, client => client.Subscribe (props), options);
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, StreamProperties props, ObservableOptions options, ISubject<Tuple> subject) {
            return Create (streamBaseClient, client => client.Subscribe (props), options, subject);
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, string sStreamName) {
            return Create (streamBaseClient, client => client.Subscribe (sStreamName));
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, string sStreamName, ObservableOptions options) {
            return Create (streamBaseClient, client => client.Subscribe (sStreamName), options);
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, string sStreamName, ObservableOptions options, ISubject<Tuple> subject) {
            return Create (streamBaseClient, client => client.Subscribe (sStreamName), options, subject);
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, StreamProperties props, string sLogicalStream, string sPredicate) {
            return Create (streamBaseClient, client => client.Subscribe (props, sLogicalStream, sPredicate));
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, StreamProperties props, string sLogicalStream, string sPredicate, ObservableOptions options) {
            return Create (streamBaseClient, client => client.Subscribe (props, sLogicalStream, sPredicate), options);
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, StreamProperties props, string sLogicalStream, string sPredicate, ObservableOptions options, ISubject<Tuple> subject) {
            return Create (streamBaseClient, client => client.Subscribe (props, sLogicalStream, sPredicate), options, subject);
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, string sStreamName, string sLogicalStream, string sPredicate) {
            return Create (streamBaseClient, client => client.Subscribe (sStreamName, sLogicalStream, sPredicate));
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, string sStreamName, string sLogicalStream, string sPredicate, ObservableOptions options) {
            return Create (streamBaseClient, client => client.Subscribe (sStreamName, sLogicalStream, sPredicate), options);
        }

        public static IConnectableObservable<Tuple> ToObservable (this StreamBaseClient streamBaseClient, string sStreamName, string sLogicalStream, string sPredicate, ObservableOptions options, ISubject<Tuple> subject) {
            return Create (streamBaseClient, client => client.Subscribe (sStreamName, sLogicalStream, sPredicate), options, subject);
        }

        static IConnectableObservable<Tuple> Create (StreamBaseClient streamBaseClient, Func<StreamBaseClient, StreamProperties> subscription) {
            return Create (streamBaseClient, subscription, ObservableOptions.Default);
        }

        static IConnectableObservable<Tuple> Create (StreamBaseClient streamBaseClient, Func<StreamBaseClient, StreamProperties> subscription, ObservableOptions options) {
            return Create (streamBaseClient, subscription, options, new Subject<Tuple> ());
        }

        static IConnectableObservable<Tuple> Create (StreamBaseClient streamBaseClient, Func<StreamBaseClient, StreamProperties> subscription, ObservableOptions options, ISubject<Tuple> subject) {
            return ObservableTupleFactory.Create (streamBaseClient, subscription, options, subject);
        }
    }
}